﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using MdDocGenerator.CodeTemplate;
using MdDocGenerator.Extensions;
using MdDocGenerator.Util;

namespace MdDocGenerator
{
    public class DefaultValueBuilder
    {
        /// <summary>
        /// 实例化的层级
        /// </summary>
        private readonly int LevelMax = 7;

        /// <summary>
        /// 
        /// </summary>
        /// <param name="type"></param>
        /// <returns></returns>
        public object Build(Type type)
        {
            var objValue = Activator.CreateInstance(type);
            BuildImpl(objValue, type);
            return objValue;
        }

        /// <summary>
        /// 属性设置实例
        /// </summary>
        /// <param name="value"></param>
        /// <param name="type"></param>
        private void BuildImpl(object value, Type type)
        {
            var properties = GetPropertys(value, type);
            var level = 1;
            while (true)
            {
                var nextProperties = new List<MyPropertyInfo>();

                //获取下级的
                foreach (var info in properties)
                {
                    try
                    {
                        var da = GetPropertys(info.Value, info.ThisType);
                        nextProperties.AddRange(da);
                    }
                    catch (Exception exception)
                    {
                        Console.WriteLine(exception);
                    }

                }

                //设置数据
                foreach (var info in properties.Where(q => q.Owner != null))
                {
                    try
                    {
                        if (info.DefaultValue != null)
                        {
                            info.PropertyInfo.SetValue(info.Owner, info.DefaultValue);
                        }
                    }
                    catch
                    {
                        continue;
                    }
                }

                //构建下次循环条件
                properties = nextProperties;
                if (!CanNext(properties) || level > LevelMax)
                {
                    break;
                }
                else
                {
                    level++;
                }
            }
        }


        private List<MyPropertyInfo> GetPropertys(object value, Type type)
        {
            return type.GetProperties().Where(q => q.CanWrite && q.IsIgnoreProperty() == false).Select(q =>
                new MyPropertyInfo()
                {
                    PropertyInfo = q,
                    Owner = value
                }).ToList();
        }

        private bool CanNext(List<MyPropertyInfo> propertys)
        {
            return propertys.Exists(q => q.ThisType != null && q.ThisType.IsClass);
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="type">实例类型</param>
        /// <param name="memberNodes">备注节点</param>
        /// <returns></returns>
        public string GetJson(object objValue, Dictionary<string, MemberNode> memberNodes)
        {
            return GetJsonFor(objValue, memberNodes, 1);
        }


        /// <summary>
        /// 
        /// </summary>
        /// <param name="type">实例类型</param>
        /// <param name="memberNodes">备注节点</param>
        /// <returns></returns>
        private string GetJsonFor(object objValue, Dictionary<string, MemberNode> memberNodes, int level)
        {
            if (level > 7)
            {
                return "";
            }
            var properties = GetPropertys(objValue, objValue.GetType());

            var builder = new MarkdownBuilder();
            builder.Header(3, "请求参数");
            List<string[]> items = new List<string[]>();
            //设置数据
            foreach (var info in properties.Where(q => q.Owner != null))
            {
                try
                {
                    var remark = memberNodes["P:" + info.Owner.ToString() + "." + info.PropertyInfo.Name];
                    var remarkText = "";
                    if (remark != null && remark.Summary != null && remark.Summary.Value != null)
                    {
                        remarkText = remark.Summary.Value.Trim();
                    }
                    var item = new string[] { $"`{info.PropertyInfo.Name}`", info.PropertyInfo.PropertyType.ToString(), remarkText };
                    items.Add(item);

                    //获取下级的
                    try
                    {
                        var da = GetPropertys(info.Value, info.ThisType);
                        if (da.Count > 0)
                        {
                            GetJsonFor(info.Value, memberNodes, ++level);
                        }
                    }
                    catch (Exception exception)
                    {
                        Console.WriteLine(exception);
                    }
                }
                catch
                {
                    continue;
                }
            }
            builder.Table(new[] { "参数", "类型", "说明" }, items);
            return builder.ToString();
        }

    }
}